package com.arron.single;

/**
 * @Classname SingleTon3
 * @Description TODO
 * @Date 2020/8/15 16:10
 * @Created by 刘
 */

/**
 * 懒汉式创建单例模式，当需要实例对象时才调用方法创建，不需要时就创建
 *
 * （1）构造器私有化
 *  (2) 用一个静态变量保存这个唯一的实例
 *  （3）调用方法时才创建对象
 *
 */
public class SingleTon3 {

    //volatile防止jvm指令重排，保证实例化过程的原子性，这样才是完整的单例模式
    private volatile static SingleTon3 INSTANCE;

    private SingleTon3(){
        System.out.println("..........SingleTon3");
    }

    public static SingleTon3 getInstance() {

        /**
         * 保证线程安全，使用双检锁(DCL)
         */
        if (INSTANCE == null){
            synchronized (SingleTon3.class){
                if (INSTANCE == null){
                    /**
                     * 创建对象的过程中有3步:
                     *  1.memory=allocate();//1.分配对象内存空间
                        2.instance(memory);//2.初始化对象
                        3.instance=memory;//3.设置instance的指向刚分配的内存地址,此时instance!=null
                     */
                    INSTANCE = new SingleTon3();
                }
            }
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
         for (int i = 1; i < 30; i++) {
             new Thread(()->{
                 SingleTon3.getInstance();
             },String.valueOf(i)).start();
         }
    }
}
